function Echo(val: string) {
  console.log(val);
  return function (
    // target 类和静态方法属性,是类, 原型方法属性.属性是原型
    target: object,
    // 方法名 属性名
    key?: any,

    descriptor?: PropertyDescriptor | number
  ) {
    console.log(val, target, key, descriptor);
  };
}
// 装饰器执行顺序,是从下到上 // 洋葱模型
@Echo("类的装饰器4")
@Echo("类的装饰器3")
@Echo("类的装饰器2")
@Echo("类的装饰器1")
class Flow {
  // 构造函数参数装饰器 构造函数 undefined 0 ;
  // constructor没有名字, 所以undefined ; 0 代表constructor参数中的第一个参数val的索引
  constructor(@Echo("构造函数参数装饰器") val: string) {}
  @Echo("静态属性装饰器")
  static type = "flow";
  @Echo("静态方法装饰器")
  static getType() {
    return this.type;
  }
  // 原型方法装饰器 原型方法 原型方法名
  // 执行顺序 >原型方法参数装饰器>原型方法装饰器>静态属性装饰器>静态方法装饰器>构造函数参数装饰器>类的修饰符
  @Echo("原型方法装饰器")
  // 实例属性装饰器>原型方法参数装饰器 原型方法 原型方法名 0 0 代表原型方法参数中的第一个参数val的索引
  flowFn(@Echo("原型方法参数装饰器") val: string) {}

  @Echo("属性访问器装饰器")
  get value() {
    return "abc";
  }
  @Echo("实例属性装饰器")
  private name = "abc";
}
// 对于实例来说的装饰器 ， 先走参数 ，在走方法
// 属性访问器装饰器
// 原型方法参数装饰器
// 原型方法装饰器
// 实例属性装饰器

// 静态属性装饰器
// 静态方法装饰器
// 构造函数参数装饰器
// 类的装饰器

// 先实例 -》 在静态的 -》 构造函数 -》 （类最后执行）

// 装饰器的使用 切片 -》 类装饰器是最后执行的

//[实例属性、方法、属性访问，定义在前面的先执行][静态属性、静态方法，定义在前面的先执行】、[类的装饰器]
//一个函数 对原来的内容不停地包裹(洋葱模型)
// 装饰器一般会搭配反射来使用
//元数据?用来描述数据的数据(备注、批注)，存起来，后续通过批注在来处理进行操作，对数据的操作
// 反射  通过批注在来处理进行操作，对数据的操作
// 反射
// 反射
export {};
